package com.kintreda.ieco_server.core.shiro;

import com.kintreda.ieco_server.bean.account.Menu;
import com.kintreda.ieco_server.bean.account.Role;
import com.kintreda.ieco_server.bean.account.User;
import com.kintreda.ieco_server.module.account.service.IUserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

@Component
public class ShiroDbRealm extends AuthorizingRealm{

	protected static Logger logger = LoggerFactory
			.getLogger(ShiroDbRealm.class);
	@Resource
	IUserService userService;

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		
		String account = (String) super.getAvailablePrincipal(principals);
		List<String> roles = new ArrayList<String>();
		List<String> menus = new ArrayList<String>();
		logger.info("账户：" + account);
		User admin = userService.getByAccount(account);
		if (admin != null) {
			// 角色
			Set<Role> roles_ = admin.getRoles();
			logger.info("角色size" + roles_.size());
			if (roles_ != null && roles_.size() > 0) {
				for (Iterator<Role> it = roles_.iterator(); it.hasNext();) {
					Role role = it.next();
					roles.add(role.getNameEn());
					// 菜单(权限)
					Set<Menu> menus_ = role.getMenus();
					logger.info("菜单size" + menus_.size());
					if (menus_ != null && menus_.size() > 0) {
						for (Iterator<Menu> it_ = menus_.iterator(); it_.hasNext();) {
							Menu menu_p = it_.next();
							if (!StringUtils.isEmpty(menu_p.getIdentification()))
								menus.add(menu_p.getIdentification());
						}
					}
				}
			}
			// 为当前用户设置角色和权限
			SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
			info.addRoles(roles);
			info.addStringPermissions(menus);
			logger.info("授权成功");
			return info;
		}
		
		return null;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
		
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
		User user = userService.getByAccount(token.getUsername());
		
		if (user == null) {
            throw new UnknownAccountException();// 没找到帐号
        }
		Object passwordObj = new SimpleHash("MD5",new String(token.getPassword()),user.getSalt(),1);
        token.setPassword(passwordObj.toString().toCharArray());

        AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(user.getUserCode(), user.getPassword(), user.getName());
        return authcInfo;

	}

	private void setSession(String key, Object value){
        Subject currentUser = SecurityUtils.getSubject();
        if(null != currentUser){
            Session session = currentUser.getSession();
            if(null != session){
                session.setAttribute(key, value);
            }
        }
    }

	public void clearAuthz(){
		Subject currentUser = SecurityUtils.getSubject();
		if(null != currentUser){
			this.clearCachedAuthorizationInfo(currentUser.getPrincipals());

	        Session session = currentUser.getSession();
	        if(null != session){
	        	this.setSession("User", null);
	        }
        }
	}

	public boolean hasPermission(String permission){
		Subject currentUser = SecurityUtils.getSubject();
		if(null != currentUser){
			try {
				currentUser.checkPermission(permission);
				return true;
			} catch (AuthorizationException e) {
				return false;
			}
        }
        return false;
	}

}
